/*************************************************************************************
 * Nombre del archivo: Nodo.java
 * Universidad del Valle de Guatemala
 * Curso: Diseño de Lenguajes de Programación
 * @author martin
 *          Martín Guzmán 08041
 * Fecha: Febrero de 2010
 * Descripción: Conteiene referencias a las
 * distintas ramificaciones de un determinado
 * árbol binario. Tiene un hijo derecho y  uno
 * izquierdo, una referencia
 * cualquier padre nombre (o bien valor)
*************************************************************************************/

public class Nodo<G> {
    private G nombre;
    public static int contador_nodos=1;
    private int numero=-1; //numero de nodo que es...
    private String texto; //texto de lo que contiene por debajo de él
    private Nodo<G> padre; //referencia al nodo padre
    private Nodo<G> hijo_derecho; //referencia al nodo hijo derecho
    private Nodo<G> hijo_izquierdo; //referencia al nodo hijo izquierdo

    /***********************************************
     * Método: Nodo
     * Uso: Inicializa el nodo.. guarda el texto
     *      de todo lo que está abajo de él
     * @return void
    ***********************************************/
    public Nodo(String texto) {
        this.texto=texto;

        this.numero=this.contador_nodos++;

        this.hijo_derecho= new Nodo<G>();
        this.hijo_izquierdo= new Nodo<G>();
        this.padre= new Nodo<G>();

    }

    /***********************************************
     * Método: Nodo
     * Uso: Constructor
     * @return void
    ***********************************************/
    private Nodo() {}


    /***********************************************
     * Método: getTexto
     * Uso: Retorna el texto de todo lo que tiene
     *      abajo de él...
     * @return String con texto
    ***********************************************/
    public String getTexto() {
        String temp=this.texto;
        return temp;
    }


    /***********************************************
     * Método: Mostrar_Nodo
     * Uso: Recorre el nodo in-order
     * @return String con el texto del nodo.
     *      imprime "(" hijo_izquierdo-raiz-hijo_derecho")"
    ***********************************************/
    public String Mostrar_Nodo() {

        String temp="";

        if(this.hijo_izquierdo.getNombre()!=null){
            temp+="("+this.hijo_izquierdo.Mostrar_Nodo();
        }
        
        if(this.getNombre()!=null){
            temp+=this.getNombre()+"";
        }

        if(this.hijo_derecho.getNombre()!=null){
            temp+=this.hijo_derecho.Mostrar_Nodo()+")";
        }
        return temp;
    }

    /***********************************************
     * Método: toString
     * Uso: Devuelve el nombre representativo del nodo
     * @return String con el nombre del nodo
    ***********************************************/
    public String toString(){
        return nombre.toString();
    }

    /***********************************************
     * Método: getNombre
     * Uso: Retorna el nombre del nodo
     * @return G con el nombre
    ***********************************************/
    public G getNombre() {
        return nombre;
    }

    /***********************************************
     * Método: setNombre
     * Uso: Asigna un nombre al nodo
     * @return void
    ***********************************************/
    public void setNombre(G nombre) {
        this.nombre = nombre;
    }

    /***********************************************
     * Método: getPadre
     * Uso: Retorna la referencia que se tiene al padre
     * @return Nodo<G> con la referencia del nodo padre
    ***********************************************/
    public Nodo<G> getPadre() {
        return padre;
    }

    /***********************************************
     * Método: setPadre
     * Uso: Asigna un padre a este nodo
     * @return void
    ***********************************************/
    public void setPadre(Nodo<G> padre) {
        this.padre = padre;
    }

    /***********************************************
     * Método: getHijo_derecho
     * Uso: Retorna el hijo que se asignó a la derecha
     * @return Nodo<G> con el hijo derecho
    ***********************************************/
    public Nodo<G> getHijo_derecho() {
        return hijo_derecho;
    }

    /***********************************************
     * Método: setHijo_derecho
     * Uso: Asigna un hijo derecho
     * @return void
    ***********************************************/
    public void setHijo_derecho(Nodo<G> hijo_derecho) {
        this.hijo_derecho = hijo_derecho;
    }

    /***********************************************
     * Método: getHijo_izquierdo
     * Uso: Retorna el hijo que se asignó a la izquierda
     * @return Nodo<G> con el hijo izquierdo
    ***********************************************/
    public Nodo<G> getHijo_izquierdo() {
        return hijo_izquierdo;
    }

    /***********************************************
     * Método: setHijo_izquierdo
     * Uso: Asigna un hijo izquierdo
     * @return void
    ***********************************************/
    public void setHijo_izquierdo(Nodo<G> hijo_izquierdo) {
        this.hijo_izquierdo = hijo_izquierdo;
    }

    /***********************************************
     * Método: getNumero
     * Uso: Retorna el número que representa al nodo
     * @return int con el número
    ***********************************************/
    public int getNumero() {
        return numero;
    }

}
